
assume cs:code
stack segment
    db 128 dup (0)
stack ends

data segment
    dw 0, 0
data ends
code segment
    start:
         mov ax, data
         mov ds, ax
         mov ax, stack
         mov ss, ax
         mov sp, 128
       
        mov ax, 0
        mov es, ax
        push es:[9 * 4] ;偏移地址
        pop ds:[0]
        push es:[9 * 4 + 2] ;段地址
        pop ds:[2]  ;将原来的int 9中断例程的入口地址保存在ds:0, ds:2单元中
        
         mov word ptr es:[9 * 4], offset new_int9   
         mov word ptr es:[9 * 4 + 2], cs    ;在中断向量表中设置新的int9中断例程的入口地址

          mov ax, 0b800h
          mov es, ax
          mov ah, 'a'
      s: mov es:[160*12 + 40 * 2], ah
         call delay
         inc ah
         cmp ah, 'z'
         jna s

        mov ax, 0
        mov es, ax
        push ds:[0]
        pop es:[9 * 4]
        push ds:[2]
        pop es:[9 * 4 +2]   ;回复中断向量表中int9中断例程的入口地址

         mov ax, 4c00h
         int 21h
    
delay:  push dx
        push ax
        mov dx, 1000h
        mov ax, 0
    s0: sub ax, 1
        sbb dx, 0
        cmp ax, 0
        jne s0
        cmp dx, 0
        jne s0
        pop ax
        pop dx
        ret

    new_int9:push ax
             push es
             push bx
             in al, 60h
              pushf
              pushf
              pop bx
              and bh, 11111100b
              push bx
              popf
              call dword ptr ds:[0]
             cmp al, 1
             jne new_int9_ret

             mov ax, 0b800h
             mov es, ax
             inc byte ptr es:[160 * 12 + 40 * 2 + 1]
            ; mov byte ptr es:[160 * 12 + 40 * 2 + 1], 02h
new_int9_ret:pop bx
             pop es
             pop ax
             iret
code ends
end start
